/**************************************************************************
 *
 * Copyright (c) 2015-2017  QIKU Company             　　　　　　　
 *                 奇酷软件（深圳）有限公司  版权所有 2015-2017
 *
 * PROPRIETARY RIGHTS of QIKU Company are involved in the  　　　　　　
 * subject matter of this material.  All manufacturing, reproduction, use,
 * and sales rights pertaining to this subject matter are governed by the
 * license agreement.  The recipient of this software implicitly accepts
 * the terms of the license.
 * 本软件文档资料是奇酷公司的资产,任何人士阅读和使用本资料必须获得
 * 相应的书面授权,承担保密责任和接受相应的法律约束.
 *
 **************************************************************************/
package com.yw.android.common.utils;

import android.content.Context;
import android.util.Log;

import com.yw.android.common.Init;
import com.yw.android.common.filelogger.AndroidLogAppender;
import com.yw.android.common.filelogger.FileAppender;
import com.yw.android.common.filelogger.LogCollecter;
import com.yw.android.common.filelogger.MultiAppender;

import java.io.File;

/**
 * 文件日志，日志信息记录到文件中，只记录重要信息
 * 日志文件路径：/[external storage]/Android/data/[package name]/log/
 *
 * @author yuanwei
 */
public class FLOG {
    /**
     * 日志标签
     */
    private static String stag = "YW";
    /**
     * 标记是否初始化过
     */
    private static boolean inited = false;
    /**
     * 日志搜集对象
     */
    private static LogCollecter logCollecter = null;

    static {
        try {
            stag = Init.getLogTag();
        } catch (Throwable t) {
            Log.w("SySearch", "init log tag failed: " + t
                    + "\n    maybe you need instance 'Init'");
        }
    }

    /**
     * 是否初始化
     *
     * @return true 已经初始化；false 未初始化
     */
    public static boolean isInited() {
        return inited;
    }

    /**
     * 初始化日志对象
     *
     * @param filename 日志文件名
     * @param context  上下文对象
     */
    public static synchronized void init(Context context,
                                         String filename) {
        if (!inited) {
            String logFilePath = null;

            try {
                // 获取日志路径
                String appDirPath = context.getExternalFilesDir(null).getParent();
                logFilePath = (appDirPath + "/log/" + filename);
                File logFile = new File(logFilePath);
                File parent = logFile.getParentFile();

                if (!parent.exists()) {
                    if (!parent.mkdirs()) {
                        Log.w("FLOG", "[" + logFilePath + "] mkdirs failed");
                        return;
                    }
                }

                AndroidLogAppender alog = new AndroidLogAppender();
                FileAppender flog = new FileAppender(logFilePath);
                flog.setMaxFileSize(1024 * 1024);                     // 日志文件为1M
                flog.setMaxRollCount(5);                              // 日志文件个数为5个

                MultiAppender mlog = new MultiAppender();
                mlog.addAppender(alog);
                mlog.addAppender(flog);

                logCollecter = new LogCollecter();
                logCollecter.setAppender(mlog)                 // 设置日志追加器
                        .setLogLevel(LogCollecter.DEBUG);  // 默认日志级别

                // 设置初始化标识
                inited = true;
                Log.i("FLOG", "[" + logFilePath + "] init file logger ...");
            } catch (Throwable t) {
                Log.w("FLOG", "[" + logFilePath + "] init file logger failed("
                        + t.getClass().getSimpleName() + "): "
                        + t.getMessage());
            }
        }
    }

    /**
     * 关闭日志对象
     */
    public static synchronized void close() {
        if (inited) {
            Log.i("FLOG", "close file logger ...");

            try {
                if (null != logCollecter) {
                    logCollecter.getAppender().close();
                    logCollecter = null;
                }
            } catch (Throwable t) {
                Log.e("FLOG", "close failed(" + t.getClass().getSimpleName() + "): "
                        + t.getMessage());
            }

            inited = false;
        }
    }

    /**
     * 设置日志标签
     *
     * @param tag 日志标签
     */
    public static void setTag(String tag) {
        Log.i("FLOG", "[" + stag + "] set log tag to " + tag);
        stag = tag;
    }

    /**
     * 打印日志，DEBUG级别
     *
     * @param tag 日志标签
     * @param msg 日志消息
     */
    public static void d(String msg) {
        try {
            if (null != logCollecter) {
                StackTraceElement stackTrace = Thread.currentThread().getStackTrace()[3];
                String fileInfo = stackTrace.getFileName() + "(" + stackTrace.getLineNumber() + ") " + stackTrace.getMethodName();
                logCollecter.debug(stag, "[fileInfo:" + fileInfo + "] " + msg);
            }
        } catch (Throwable t) {
            Log.e("LOG", "debug failed(" + t.getClass().getSimpleName() + "): "
                    + t.getMessage());
        }
    }

    /**
     * 打印日志，INFO级别
     *
     * @param msg 日志消息
     */
    public static void i(String msg) {
        try {
            if (null != logCollecter) {
                StackTraceElement stackTrace = Thread.currentThread().getStackTrace()[3];
                String fileInfo = stackTrace.getFileName() + "(" + stackTrace.getLineNumber() + ") " + stackTrace.getMethodName();
                logCollecter.info(stag, "[fileInfo:" + fileInfo + "] " + msg);
            }
        } catch (Throwable t) {
            Log.e("LOG", "info failed(" + t.getClass().getSimpleName() + "): "
                    + t.getMessage());
        }
    }

    /**
     * 打印日志，WARN级别
     *
     * @param msg 日志消息
     */
    public static void w(String msg) {
        try {
            StackTraceElement stackTrace = Thread.currentThread().getStackTrace()[3];
            String fileInfo = stackTrace.getFileName() + "(" + stackTrace.getLineNumber() + ") " + stackTrace.getMethodName();
            logCollecter.warn(stag, "[fileInfo:" + fileInfo + "] " + msg);
        } catch (Throwable t) {
            Log.e("LOG", "warn failed(" + t.getClass().getSimpleName() + "): "
                    + t.getMessage());
        }
    }

    /**
     * 打印日志，ERROR级别
     *
     * @param msg 日志消息
     */
    public static void e(String msg) {
        try {
            if (null != logCollecter) {
                StackTraceElement stackTrace = Thread.currentThread().getStackTrace()[3];
                String fileInfo = stackTrace.getFileName() + "(" + stackTrace.getLineNumber() + ") " + stackTrace.getMethodName();
                logCollecter.error(stag, "[fileInfo:" + fileInfo + "] " + msg);
            }
        } catch (Throwable t) {
            Log.e("LOG", "error failed(" + t.getClass().getSimpleName() + "): "
                    + t.getMessage());
        }
    }

    /**
     * 打印日志，ERROR级别
     *
     * @param msg 日志消息
     * @param t   异常对象
     */
    public static void e(String msg, Throwable t) {
        if ((null != logCollecter) && (null != t)) {
            try {
                StackTraceElement stackTrace = Thread.currentThread().getStackTrace()[3];
                String fileInfo = stackTrace.getFileName() + "(" + stackTrace.getLineNumber() + ") " + stackTrace.getMethodName();
                logCollecter.error(stag, "[fileInfo:" + fileInfo + "] " + msg, t);
            } catch (Throwable e) {
                Log.e("LOG", "error failed(" + t.getClass().getSimpleName() + "): "
                        + t.getMessage());
            }
        }
    }
}
